// t1, f2
package ViewApplication;

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Dimension;
import java.awt.EventQueue;
import java.awt.Font;
import java.awt.GridLayout;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JProgressBar;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.ListSelectionModel;
import javax.swing.ScrollPaneConstants;
import javax.swing.SwingConstants;
import javax.swing.border.EmptyBorder;
import javax.swing.filechooser.FileFilter;
import javax.swing.filechooser.FileNameExtensionFilter;

import ControllerApplication.AudioProcessingFactory;
import ControllerApplication.AudioProcessingLocal;
import ControllerApplication.AudioProcessingMethods;
import ControllerApplication.Sounds;
import UtilsApplication.HandleAudioUtil;

public class MainWindow {

    private JFrame frmPrzetwarzanieDzwiekuuukasz;
    private JTable table;
    private JComboBox<String> comboBox;
    final JFileChooser fc = new JFileChooser();
    JLabel lblZrobione;
    
    private Sounds sounds;
    AudioProcessingLocal audioProcessing;

    private Map<Integer,SoundWindow> showedSoundsWindow;

    /**
     * Launch the application.
     */
    public static void main( String[] args ) {
        EventQueue.invokeLater( new Runnable() {
            public void run() {
                try {
                    MainWindow window = new MainWindow();
                    window.frmPrzetwarzanieDzwiekuuukasz.setVisible( true );
                } catch ( Exception e ) {
                    e.printStackTrace();
                }
            }
        } );
    }

    /**
     * Create the application.
     */
    public MainWindow() {
        initialize();
    }

    /**
     * Initialize the contents of the frame.
     */
    private void initialize() {

        frmPrzetwarzanieDzwiekuuukasz = new JFrame();
        frmPrzetwarzanieDzwiekuuukasz.setTitle("Przetwarzanie dzwieku Łukasz Bujacz, Paweł Lebelt v0.1");
        frmPrzetwarzanieDzwiekuuukasz.setBounds( 100, 100, 700, 400 );
        frmPrzetwarzanieDzwiekuuukasz.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE );
        frmPrzetwarzanieDzwiekuuukasz.getContentPane().setLayout(new BorderLayout(0, 0));
        
                // tabela
                table = new JTable();    
                table.setAutoResizeMode(JTable.AUTO_RESIZE_ALL_COLUMNS);
                table.setModel( new MainTableModel() );
                JScrollPane scrollPane = new JScrollPane(table);
                frmPrzetwarzanieDzwiekuuukasz.getContentPane().add(scrollPane, BorderLayout.CENTER);
                scrollPane.setPreferredSize(new Dimension(23, 240));
                scrollPane.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_ALWAYS);
                table.addMouseListener(new MouseAdapter() {
                    @Override
                    public void mouseClicked(MouseEvent arg0) {
                        clickedTableListener(arg0);
                    }
                });
                table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
                
                JPanel panel_1 = new JPanel();
                frmPrzetwarzanieDzwiekuuukasz.getContentPane().add(panel_1, BorderLayout.EAST);
                                                                                panel_1.setLayout(new GridLayout(0, 1));
                                                                                
                                                                                JPanel panel_3 = new JPanel();
                                                                                panel_3.setBorder(new EmptyBorder(20, 0, 0, 0));
                                                                                panel_1.add(panel_3);
                                                                                                        panel_3.setLayout(new GridLayout(4,1));
                                                                                                
                                                                                                        JButton btnWczytajObraz = new JButton("Wczytaj");
                                                                                                        panel_3.add(btnWczytajObraz);
                                                                                                        btnWczytajObraz.addActionListener(new ActionListener() {
                                                                                                            public void actionPerformed(ActionEvent arg0) {
                                                                                                                loadSoundListener(arg0);
                                                                                                            }
                                                                                                        });
                                                                                                
                                                                                                        JButton btnZapiszObraz = new JButton("Zapisz");
                                                                                                        panel_3.add(btnZapiszObraz);
                                                                                                        
                                                                                                        JButton btnNewButton_1 = new JButton("Usuń");
                                                                                                        btnNewButton_1.addActionListener(new ActionListener() {
                                                                                                            public void actionPerformed(ActionEvent arg0) {
                                                                                                                deleteSounds();
                                                                                                            }
                                                                                                        });
                                                                                                        panel_3.add(btnNewButton_1);
                                                                                                        
                                                                                                        lblZrobione = new JLabel("ZROBIONE");
                                                                                                        lblZrobione.setFont(new Font("Tahoma", Font.PLAIN, 22));
                                                                                                        panel_3.add(lblZrobione);
                                                                                                        lblZrobione.setForeground(Color.GREEN);
                                                                                                        lblZrobione.setHorizontalAlignment(SwingConstants.CENTER);
                                                                                                        lblZrobione.setVisible( false );
                                                                                                btnZapiszObraz.addActionListener(new ActionListener() {
                                                                                                    public void actionPerformed(ActionEvent e) {               
                                                                                                        saveSoundListener(e);
                                                                                                    }
                                                                                                });
                                                        
                                                        JPanel panel_4 = new JPanel();
                                                        panel_1.add(panel_4);
                                                                panel_4.setLayout(new GridLayout(0,1));
                                                        
                                                                JLabel lblMetodaPrzetwarzania = new JLabel("Metoda przetwarzania");
                                                                panel_4.add(lblMetodaPrzetwarzania);

                                                                        comboBox = new JComboBox<String>(AudioProcessingMethods.methods);
                                                                        panel_4.add(comboBox);
                                                                        
                                                                                JButton btnNewButton = new JButton("Pokaż");
                                                                                panel_4.add(btnNewButton);
                                                                                
                                                                                        JButton btnKonfiguracja = new JButton("Konfiguracja");
                                                                                        panel_4.add(btnKonfiguracja);
                                                                                        
                                                                                                JButton btnPrzetwarzaj = new JButton("Przetwarzaj");
                                                                                                panel_4.add(btnPrzetwarzaj);
                                                                                                btnPrzetwarzaj.addActionListener(new ActionListener() {
                                                                                                    public void actionPerformed(ActionEvent e) {
                                                                                                        processingAudio(e);
                                                                                                    }
                                                                                                });
                                                                                        btnKonfiguracja.addActionListener(new ActionListener() {
                                                                                            public void actionPerformed(ActionEvent e) {
                                                                                                openProcessingAudioWindow(e);
                                                                                            }
                                                                                        });
                                                                                btnNewButton.setVisible(false);
                                                                                btnNewButton.addActionListener(new ActionListener() {
                                                                                    public void actionPerformed(ActionEvent arg0) {
                                                                                        showSoundListener(arg0);
                                                                                    }});
                                                                        comboBox.addItemListener(new ItemListener() {
                                                                            public void itemStateChanged(ItemEvent arg0) {
                                                                                updateAudioProcessingMethod();
                                                                            }
                                                                        });
                        
                        JPanel panel_2 = new JPanel();
                        frmPrzetwarzanieDzwiekuuukasz.getContentPane().add(panel_2, BorderLayout.SOUTH);
                        
                                JLabel lblPostp = new JLabel("Progres");
                                lblPostp.setVisible(false);
                                panel_2.add(lblPostp);
                                
                                        JProgressBar progressBar = new JProgressBar();
                                        progressBar.setVisible(false);
                                        panel_2.add(progressBar);

        // inicjacja podstawowych obiektow klas potrzebnych do dzialania aplikacji
        initComponents();

        updateTableSounds();
    }

    private void initComponents() {
        sounds = new Sounds();
        showedSoundsWindow = new HashMap<>();
        updateAudioProcessingMethod();
    }

    private void updateTableSounds() {

        MainTableModel model =  (MainTableModel) table.getModel();
        model.setRowCount(0);
        List<String []> list = sounds.getAllInformation();
        for(String [] l : list) {
            model.addRow( l );
        }
    }

    private void loadSoundListener(ActionEvent arg0) {
        FileFilter audioFilter = new FileNameExtensionFilter(
                "Wav files", new String [] {"wav"});

        fc.setAcceptAllFileFilterUsed(false);
        fc.addChoosableFileFilter( audioFilter ); 

        //In response to a button click:
        int returnVal = fc.showOpenDialog(frmPrzetwarzanieDzwiekuuukasz);

        if (returnVal == JFileChooser.APPROVE_OPTION) {
            File file = fc.getSelectedFile();
            sounds.addSound( HandleAudioUtil.loadSound( file ) );
        }        
        updateTableSounds();
    }

    private void saveSoundListener(ActionEvent arg0) {
        if(table.getSelectedRow() >= 0) {
            FileFilter audioFilter = new FileNameExtensionFilter(
                    "Wav files", new String [] {"wav"});

            fc.setAcceptAllFileFilterUsed(false);
            fc.addChoosableFileFilter( audioFilter );

            File fileTmp = new File(sounds.getSound( table.getSelectedRow() ).getName());
            fc.setSelectedFile( fileTmp );
            int returnVal = fc.showSaveDialog(frmPrzetwarzanieDzwiekuuukasz);

            if (returnVal == JFileChooser.APPROVE_OPTION) {
                File file = fc.getSelectedFile();
                HandleAudioUtil.saveAudio( sounds.getSound( table.getSelectedRow()), file );
            }  
        }
    }

    private void showSoundListener(ActionEvent arg0) {
        if(table.getSelectedRow() >= 0) {

            if(showedSoundsWindow.containsKey( table.getSelectedRow() )) {
                SoundWindow imgWindow = showedSoundsWindow.get( table.getSelectedRow() );
                imgWindow.setOnTheTop();
            } else {

                SoundWindow imgWindow = new SoundWindow( sounds.getSound( table.getSelectedRow() ));
                showedSoundsWindow.put( table.getSelectedRow(), imgWindow );
            }
        }
    }

    private void clickedTableListener(MouseEvent  arg0) {
        if (arg0.getClickCount() == 2) {
            showSoundListener(null);
        }
    }

    private void updateAudioProcessingMethod() {
        audioProcessing = AudioProcessingFactory.getAudioProcessing( comboBox.getSelectedIndex(), (String)comboBox.getSelectedItem(), 
                frmPrzetwarzanieDzwiekuuukasz.getX() + frmPrzetwarzanieDzwiekuuukasz.getWidth(),
                frmPrzetwarzanieDzwiekuuukasz.getY(), sounds.getAllSounds());
    }

    private void openProcessingAudioWindow(ActionEvent e) {
        audioProcessing.showWindow();
    }
    
    private void processingAudio(ActionEvent e) {
        if(table.getSelectedRow() >= 0) {
            final int rows [] = table.getSelectedRows();
            Thread t = null;
            for(int i =0; i < rows.length; i++) {
                    t = new Thread(new MyRunnable(rows[i]));
                    t.start();
                    try {
                        t.join();
                    } catch ( InterruptedException e1 ) {
                        e1.printStackTrace();
                    }
                }
        }
        
    }
    
    private void deleteSounds() {
        
        int [] rows = table.getSelectedRows();
        for(int i = rows.length - 1; i >= 0; i--) {
            sounds.deteleSound( rows[i]);
        }
        updateTableSounds();
    }
    
    private class MyRunnable implements Runnable {
        private int parameter;
        public MyRunnable(int parameter) {
           this.parameter = parameter;
        }

        public void run() {
            lblZrobione.setVisible( false );
            int selected = parameter;
            try {
                sounds.addSound(audioProcessing.processing( sounds.getSound( selected ) ));
            } catch (UnsupportedOperationException e) {
                sounds.addSounds(audioProcessing.processingList( sounds.getSound( selected ) ));
            }
            updateTableSounds();
            lblZrobione.setVisible( true );
            table.setRowSelectionInterval( selected,selected );
        }
     }
}
